package com.tianji.learning.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.constants.CacheConstants;
import com.tianji.common.exceptions.BizIllegalException;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.entity.InteractionQuestion;
import com.tianji.learning.domain.entity.PointsBoard;
import com.tianji.learning.domain.query.PointsBoardQuery;
import com.tianji.learning.domain.vo.PointsBoardItemVO;
import com.tianji.learning.domain.vo.PointsBoardVO;
import com.tianji.learning.interfaces.UserIdFunction;
import com.tianji.learning.mapper.PointsBoardMapper;
import com.tianji.learning.service.IPointsBoardService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.learning.service.UserQueryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 学霸天梯榜 服务实现类
 * </p>
 *
 * @author author
 */
@Slf4j
@Service
public class PointsBoardServiceImpl extends ServiceImpl<PointsBoardMapper, PointsBoard> implements IPointsBoardService {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private UserClient userClient;
    @Autowired
    private UserQueryService userQueryService;

    @Override
    public PointsBoardVO queryPointsBoard(PointsBoardQuery query) {
        PointsBoardVO vo = new PointsBoardVO();
        //s赛季id
        Long userId = UserContext.getUser();
        Long season = query.getSeason();
        if (season == null || season <= 0) {
            //当前赛季
            //查询我的信息1
            String day = LocalDateTimeUtil.format(LocalDateTime.now(), "yyyyMM");
            String key = CacheConstants.POINTS_BOARD + day;
            //我的积分
            Double score = redisTemplate.opsForZSet().score(key, userId);
            vo.setPoints(score == null ? 0 : score.intValue());
            //我的排名
            Long rank = redisTemplate.opsForZSet().reverseRank(key, userId);
            vo.setRank(rank == null ? -1 : rank.intValue() + 1);
            //分页查询  //起始索引   终止索引
            int startIndex = (query.getPageNo() - 1) * query.getPageSize();
            int endIndex = query.getPageNo() * query.getPageSize() - 1;
            Set<ZSetOperations.TypedTuple<String>> typedTuples = redisTemplate.opsForZSet().reverseRangeWithScores(key, startIndex, endIndex);
            if (CollectionUtil.isEmpty(typedTuples)) {
                return vo;
            } else {
                List<PointsBoardItemVO> pointsBoardItemVOS = new ArrayList<>();
                ArrayList<ZSetOperations.TypedTuple<String>> typedTupleList = new ArrayList<>(typedTuples);
                for (int i = 0; i < typedTupleList.size(); i++) {
                    PointsBoardItemVO itemVO = new PointsBoardItemVO();
                    ZSetOperations.TypedTuple<String> stringTypedTuple = typedTupleList.get(i);
                    Double userScore = stringTypedTuple.getScore();
                    String userIdstring  = stringTypedTuple.getValue();
                    itemVO.setPoints(userScore.intValue());
                    itemVO.setRank(startIndex+i+1);
                    itemVO.setName(userIdstring);
                    itemVO.setUserId(Long.parseLong(userIdstring));
                    pointsBoardItemVOS.add(itemVO);
                }
                // feign, UserClient   id->name
//                List<Long> userIds = pointsBoardItemVOS.stream().map(PointsBoardItemVO::getName).map(Long::parseLong).collect(Collectors.toList());
                Map<Long, UserDTO> userMap =userQueryService.getUserMap(pointsBoardItemVOS);
                for (PointsBoardItemVO pointsBoardItemVO : pointsBoardItemVOS) {
                    UserDTO user = userMap.get(Long.parseLong(pointsBoardItemVO.getName()));
                    pointsBoardItemVO.setName(user==null?"":user.getName());
                }
                vo.setBoardList(pointsBoardItemVOS);
            }

        } else {
            //历史赛季
            String tableName = CacheConstants.POINTS_BOARD_PREFIX + season;
            PointsBoardItemVO itemVO =  this.baseMapper.queryByUserId(tableName, userId);
            if(itemVO != null){
                vo.setRank(itemVO.getRank());
                vo.setPoints(itemVO.getPoints());
            }
            // 分页查询当前页列表
            int startIndex = (query.getPageNo()-1)*query.getPageSize();
            List<PointsBoardItemVO> itemVos = this.baseMapper.selectPageData(tableName,startIndex, query.getPageSize());
            if(!CollUtils.isEmpty(itemVos)){
                // userId - > userName
                Map<Long, UserDTO> userMap = userQueryService.getUserMap(itemVos);
                for (PointsBoardItemVO item : itemVos) {
                    UserDTO user = userMap.get(item.getUserId());
                    item.setName(user==null?"":user.getName());
                }
            }
            vo.setBoardList(itemVos);

        }
        return vo;
    }
    /*private Map<Long, UserDTO> getUserMap(List<Long> userIds){
        List<UserDTO> users = userClient.queryUserByIds(userIds);
        if(CollUtils.isEmpty(users)){
            log.info("查询不到用户信息：{}", userIds);
            throw new BizIllegalException("网络异常");
        }
        Map<Long, UserDTO> userMap = users.stream().collect(Collectors.toMap(UserDTO::getId, Function.identity()));
        return CollUtils.isEmpty(userMap)?new HashMap<>():userMap;
    }*/
}
